package com.foxit.pdf2pdf.web.controller;

import com.foxit.pdf2pdf.web.common.Base64;
import com.foxit.pdf2pdf.web.common.GetBean;
import com.foxit.pdf2pdf.web.common.TFSFileUntil;
import com.foxit.pdf2pdf.web.common.TaskStore;
import com.foxit.tbschedule.task.ConverTranslateContent;
import com.foxit.tbschedule.task.ConverTranslatePDFInfo;
import com.foxit.tbschedule.task.ConverTranslateUpdateLoad;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.query.Query;
import com.google.code.morphia.query.UpdateOperations;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UploadController
{
  protected static final Logger logger = Logger.getLogger(UploadController.class);
  private final String defaultdir = "/usr/share/tomcat/latest/temp/";
  private static String defaulturl;
  private final String success = "success";
  private final String docidnew = "new";
  private final String suffixstr = ".pdf";
  private String target = null;
  static
  {
    init();
  }
  
  	public String getDefaultdir() {
		return defaultdir;
	}
  	public String getDocidnew() {
		return docidnew;
	}
	public String getSuffixstr() {
		return suffixstr;
	}
  public static String getDefaulturl()
  {
    return defaulturl;
  }
  public String getSuccess() {
    return this.success;
  }
  public String getTarget() {
    return this.target;
  }

  public void setTarget(String target) {
    this.target = target;
  }

  @RequestMapping({"/UploadPDF.do"})
  public String uploadPDF(HttpServletRequest request, HttpServletResponse response) throws IOException, JSONException
  {
    //logger.debug("start upload");
    //logger.debug("defaulturl:" + getDefaulturl());
    request.setCharacterEncoding("UTF-8");
    response.setContentType("text/html; charset=UTF-8");
    JSONObject json = new JSONObject();
    boolean isSuccess = false;
    if (ServletFileUpload.isMultipartContent(request)) {
      DiskFileItemFactory factory = new DiskFileItemFactory();
      ServletFileUpload upload = new ServletFileUpload(factory);
      upload.setHeaderEncoding("UTF-8");
      
      List<FileItem> items = new ArrayList<FileItem>();
      try {
        items = upload.parseRequest(request);
      } catch (FileUploadException e) {
        logger.error(e.getMessage());
        json.put(getSuccess(), isSuccess);
        response.getWriter().write(json.toString());
        return null;
      }
      String docid = null;
      String target = null;
      for(FileItem fileItem : items){//先获取语言
    	  if (fileItem.isFormField()) {
    		  String name = fileItem.getFieldName();
    		  if("target".equals(name)){
    			  target = fileItem.getString("UTF-8");
    			  break;
    		  }
    	  }
      }
      //logger.debug("FileItem.size:" + items.size());
      for (FileItem fileItem : items) {
        if (!fileItem.isFormField()) {
          try
          {
            String fileName = fileItem.getName();
            //logger.debug("fileName:" + fileName);
            String fileEnd = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
            String uuid = UUID.randomUUID().toString();
            docid = uuid;
            StringBuffer sbRealPath = new StringBuffer();
            sbRealPath.append(getDefaultdir()).append(uuid).append(".").append(fileEnd);
            logger.debug("sbRealPath:" + sbRealPath.toString());

            File file = new File(sbRealPath.toString());
            fileItem.write(file);

            byte[] data = File2byte(sbRealPath.toString());

            String patch = getDefaulturl() + uuid + getSuffixstr();
            boolean flag = TFSFileUntil.saveContent(patch, data);
            //logger.debug("flag:" + flag);
            if (!flag) {
            	int count = 0;
    			while (count < 3) {
    				flag = TFSFileUntil.saveContent(patch, data);
    				if(flag){
    					break;
    				}
    				count++;
    			}
    			//上传失败
    			saveToDB(uuid,fileName,fileItem.getSize(),flag);
    			if(!flag){
    			  if(file.exists()){
    				  logger.debug("delete src file:" + uuid + getSuffixstr());
    				  file.delete();
    			  }	
	              logger.error("upload file to tfs fail!");
	              json.put(getSuccess(), isSuccess);
	              response.getWriter().write(json.toString());
	              return null;
    			}
            }
            
            if(file.exists()){
            	file.delete();
            }
            saveToDB(uuid,fileName,fileItem.getSize(),true);
            //发送拆分命令
            //logger.debug("start partition task");
            TaskStore task = new TaskStore();
            task.pushTask(uuid,"0", target,-1,fileName);
            fileItem.delete();
          } catch (Exception e) {
            logger.error(e.getMessage());
            json.put(getSuccess(), isSuccess);
            response.getWriter().write(json.toString());
            return null;
          }
        }else {
          //logger.debug("isFormField:" + true);
          String fieldName = fileItem.getFieldName();

          String fieldValue = fileItem.getString("UTF-8");
          request.setAttribute(fieldName, fieldValue);
        }
      }
      isSuccess = true;
      json.put(getSuccess(), isSuccess);
      json.put("docId", docid);
      response.getWriter().write(json.toString());
    } else {
      json.put(getSuccess(), isSuccess);
      response.getWriter().write(json.toString());
      logger.debug("UploadFileFailed");
    }
    return null;
  }

  private void saveToDB(String docid,String fileName,long size,boolean flag){
	  logger.debug(docid + " saveToDB start");
	  Datastore datastore = GetBean.getDatastore();
	  SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	  ConverTranslateUpdateLoad ctu = datastore.createQuery(ConverTranslateUpdateLoad.class).field("documentId").equal(docid).get();
	  if(!flag){
		  if(ctu == null){
			  ctu = new ConverTranslateUpdateLoad();
			  ctu.setDocumentId(docid);
			  ctu.setFileName(fileName);
			  ctu.setTargetLan(getTarget());
			  ctu.setFileSize(size);
			  ctu.setCreateDate(df.format(new Date()));
			  ctu.setStatus(-1);
			  datastore.save(ctu);
			}
	  }else{
		  if(ctu == null){ 
			  ctu = new ConverTranslateUpdateLoad();
			  ctu.setDocumentId(docid);
			  ctu.setFileName(fileName);
			  ctu.setTargetLan(getTarget());
			  ctu.setFileSize(size);
			  ctu.setCreateDate(df.format(new Date()));
			  ctu.setStatus(0);
			  datastore.save(ctu);
			}
	  }
	  logger.debug(docid + " saveToDB end");
	  return;
  }
  @RequestMapping({"/GetSchedualeMsg.do"})
  public String getSchedualeMsg(HttpServletRequest request, HttpServletResponse response) throws JSONException, IOException
  {
	  request.setCharacterEncoding("UTF-8");
	  JsonObject json  = new JsonParser().parse(new BufferedReader(new InputStreamReader(request.getInputStream()))).getAsJsonObject() ;
	  String status = json.get("status").getAsString();
	  String docid = json.get("docId").getAsString();
	  logger.debug(docid + " getSchedualeMsg start task status:" + status);
	  Datastore datastore = GetBean.getDatastore();
	  if("0".equals(status)){
		  String target = json.get("target").getAsString();
		  List<ConverTranslateContent> ctcList = (List<ConverTranslateContent>)datastore.createQuery(ConverTranslateContent.class).field("documentId").equal(docid).asList();
		  //logger.debug("start translate tasks...");
		  for(ConverTranslateContent ctc : ctcList){
			  int index = ctc.getIndex();
			  TaskStore task = new TaskStore();
	           task.pushTask(docid,"1", target,index,"");
	           //logger.debug("translate task " + index + "  start...");
		  }
	  }else if("1".equals(status)){
		  	  String target = json.get("target").getAsString();
			  List<ConverTranslateContent> ctcList = (List<ConverTranslateContent>)datastore.createQuery(ConverTranslateContent.class).field("documentId").equal(docid).asList();
			  boolean flag = true;
			  for(ConverTranslateContent ctc : ctcList){
				 if(ctc.getTranslateStatus() == 0){//查看是否有未翻译完的
					 flag = false;
					 break;
				 }
			  }
			  
			  if(flag){
				  Query<ConverTranslatePDFInfo> q = datastore.createQuery(ConverTranslatePDFInfo.class).field("_id").equal(Base64.encode(docid)).field("convertStatus").equal(0);
				  UpdateOperations<ConverTranslatePDFInfo> u = datastore.createUpdateOperations(ConverTranslatePDFInfo.class).set("convertStatus", 1);
				  
				  ConverTranslatePDFInfo t = datastore.findAndModify(q, u);
				  if(t != null){
					  //logger.debug("start piece task...");
					  TaskStore task = new TaskStore();
					  task.pushTask(docid,"2", target,-1,"");
				  }
			  }
	  }else if("2".equals(status)){
		  
	  }
	  logger.debug(docid + " getSchedualeMsg end task status:" + status);
	  return null;
  }
  @RequestMapping({"/GetTranslateStatus.do"})
  public String getTranslateStatus(HttpServletRequest request, HttpServletResponse response) throws JSONException, IOException
  {
    String docIdtmp = request.getParameter("docId");
    //logger.debug(docIdtmp + " getTranslateStatus start");
    //logger.debug("docId:" + docIdtmp);
    JSONObject json = new JSONObject();
    int status = 0;
    boolean flag = false;
    String url = null;
    try
    {
      Datastore datastore = GetBean.getDatastore();
      //logger.debug("datastore:" + datastore);

        ConverTranslatePDFInfo pdfInfo = (ConverTranslatePDFInfo)(datastore.createQuery(ConverTranslatePDFInfo.class).field("_id").equal(Base64.encode(docIdtmp))).get();
        if (pdfInfo != null) {
          status = pdfInfo.getConvertStatus();
        }
        
	      if (status == 2) {
	        flag = true;
	        url = getDefaulturl() + docIdtmp + getDocidnew() + getSuffixstr();
	      }
      
      File file = new File(getDefaulturl() + docIdtmp + getSuffixstr());
      if(file.exists()){
    	  logger.debug("delete src file");
    	  file.delete();
      }
      //logger.debug("translate end...");
      json.put(getSuccess(), flag);
      json.put("url", url);
      json.put("status", status);
      response.getWriter().write(json.toString());
    } catch (Exception e) {
      logger.error(e.getMessage());
      json.put(getSuccess(), false);
      json.put("status", -1);
      response.getWriter().write(json.toString());
    }
		logger.debug(docIdtmp + " getTranslateStatus end result:" + flag);
    return null;
  }

  public static void init()
  {
    try {
      URL appContextBeansXmlPath = UploadController.class.getResource("/ConversionContextBeans.xml");
      UrlResource appContextBeansXmlResouce = new UrlResource(appContextBeansXmlPath);
      GetBean.InitContext(appContextBeansXmlResouce);
      
      Properties prop = new Properties();
      InputStream in =  Thread.currentThread().getContextClassLoader().getResourceAsStream("readerConfig.properties");
      //logger.debug(in);
      prop.load(in);
      defaulturl = prop.getProperty("FOXIT_TFS_URL").trim();
      //logger.debug(defaulturl);
    }
    catch (Exception ex)
    {
      logger.error("Spring initialize failed." + ex);
      return;
    }
  }

  private byte[] File2byte(String filePath)
  {
    byte[] buffer = null;
    try
    {
      File file = new File(filePath);
      FileInputStream fis = new FileInputStream(file);
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      byte[] b = new byte[1024];
      int n;
      while ((n = fis.read(b)) != -1)
      {
        bos.write(b, 0, n);
      }
      fis.close();
      bos.close();
      buffer = bos.toByteArray();
    }
    catch (FileNotFoundException e)
    {
      e.printStackTrace();
      logger.error(e.getMessage());
    }
    catch (IOException e)
    {
      e.printStackTrace();
      logger.error(e.getMessage());
    }
    return buffer;
  }
}